home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 10 / FM Towns Free Software Collection 10.iso / ms_dos / tool / fwcp / src / menu.c < prev    next >
Text File  |  1995-03-15  |  7KB  |  322 lines

  1. #include    <stdio.h>
  2. #include    <stdlib.h>
  3. #include    <malloc.h>
  4. #include    <string.h>
  5. #include    <ctype.h>
  6.  
  7. #ifdef    MSDOS
  8. #include    <jctype.h>
  9. #endif
  10.  
  11. #include    "defs.h"
  12. #include    "key.h"
  13.  
  14. void    wind(int sx, int sy, int wd, int ht)
  15. {
  16.     int n, i;
  17.  
  18. #ifdef    MSDOS
  19.     sx -= 1;
  20.     sy -= 1;
  21.  
  22.     LOCATE(sx, sy++);
  23.     PUTANK(0x9C);
  24.     for ( n = 0 ; n < wd ; n++ )
  25.     PUTANK(0x95);
  26.     PUTANK(0x9D);
  27.  
  28.     for ( i = 0 ; i < ht ; i++ ) {
  29.     LOCATE(sx, sy++);
  30.     PUTANK(0x96);
  31.     for ( n = 0 ; n < wd ; n++ )
  32.         PUTANK(' ');
  33.     PUTANK(0x96);
  34.     }
  35.  
  36.     LOCATE(sx, sy++);
  37.     PUTANK(0x9E);
  38.     for ( n = 0 ; n < wd ; n++ )
  39.     PUTANK(0x95);
  40.     PUTANK(0x9F);
  41. #else
  42.     sx -= 2;
  43.     sy -= 1;
  44.  
  45.     LOCATE(sx, sy++);
  46.     PUTS("┌");
  47.     for ( n = 0 ; n < wd ; n += 2 )
  48.     PUTS("─");
  49.     PUTS("┐");
  50.  
  51.     for ( i = 0 ; i < ht ; i++ ) {
  52.     LOCATE(sx, sy++);
  53.     PUTS("│");
  54.     for ( n = 0 ; n < wd ; n += 2 )
  55.         PUTS("  ");
  56.     PUTS("│");
  57.     }
  58.  
  59.     LOCATE(sx, sy++);
  60.     PUTS("└");
  61.     for ( n = 0 ; n < wd ; n += 2 )
  62.     PUTS("─");
  63.     PUTS("┘");
  64. #endif
  65. }
  66. int    hash_menu(int x, int y, int len, char *arg[])
  67. {
  68.     int i, n;
  69.     int ent = 0;
  70.     int max = 16;
  71.     int ext = 1;
  72.     char **av;
  73.     short *nv;
  74.     char tmp[36];
  75.     char *p;
  76.  
  77.     if ( (av = (char **)malloc(sizeof(char *) * max)) == NULL )
  78.         return ERR;
  79.  
  80.     if ( len >= 32 )
  81.     len = 32;
  82.  
  83. LOOP:
  84.     for ( n = 0 ; arg[n] != NULL ; n++ ) {
  85.     strncpy(tmp, arg[n], len);
  86.     tmp[len] = '\0';
  87.     for ( p = tmp ; *p != '\0' ; ) {
  88.         if ( iskanji(p[0]) ) {
  89.         if ( !iskanji2(p[1]) )
  90.             break;
  91.         p += 2;
  92.         } else
  93.         p++;
  94.     }
  95.     *p = '\0';
  96.  
  97.     for ( i = 0 ; i < ent ; i++ ) {
  98.         if ( strcmp(av[i], tmp) == 0 )
  99.         break;
  100.     }
  101.     if ( ent > 0 && i < ent )
  102.         continue;
  103.  
  104.     av[ent++] = strdup(tmp);
  105.         if ( ent >= max ) {
  106.             max += 32;
  107.             if ( (av = (char **)realloc(av, sizeof(char *) * max)) == NULL )
  108.                 return ERR;
  109.         }
  110.     }
  111.     av[ent] = NULL;
  112.  
  113.     if ( n == ent ) {
  114.         for ( n = 0 ; n < ent ; n++ )
  115.             free(av[n]);
  116.     free(av);
  117.     return menu(x, y, 0, arg);
  118.  
  119.     } else if ( ent <= 1 ) {
  120.         for ( n = 0 ; n < ent ; n++ )
  121.             free(av[n]);
  122.     ent = 0;
  123.     if ( len >= 16 )
  124.         return menu(x, y, 0, arg);
  125.     len += 2;
  126.     goto LOOP;
  127.  
  128.     } else if ( (n = menu(x, y, 0, av)) < 0 ) {
  129.         for ( n = 0 ; n < ent ; n++ )
  130.             free(av[n]);
  131.     free(av);
  132.     return ERR;
  133.     }
  134.  
  135.     strcpy(tmp, av[n]);
  136.     len = strlen(tmp);
  137.  
  138.     for ( n = 0 ; n < ent ; n++ )
  139.         free(av[n]);
  140.     ent = 0;
  141.  
  142.     if ( (nv = (short *)malloc(sizeof(short) * max)) == NULL )
  143.         return ERR;
  144.  
  145.     for ( n = 0 ; arg[n] != NULL ; n++ ) {
  146.     if ( strncmp(arg[n], tmp, len) != 0 )
  147.         continue;
  148.     nv[ent]   = n;
  149.     av[ent++] = arg[n];
  150.         if ( ent >= max ) {
  151.             max += 32;
  152.             if ( (av = (char **)realloc(av, sizeof(char *) * max)) == NULL ||
  153.                  (nv = (short *)realloc(nv, sizeof(short) * max)) == NULL )
  154.                 return ERR;
  155.         }
  156.     }
  157.     av[ent] = NULL;
  158.  
  159.     if ( ent >= 20 ) {
  160.     if ( (n = hash_menu(x + 4, y + 1, len + 2, av)) >= 0 )
  161.         n = nv[n];
  162.     } else if ( (n = menu(x + 4, y + 1 , 0, av)) >= 0 )
  163.     n = nv[n];
  164.  
  165.     free(nv);
  166.     free(av);
  167.  
  168.     return n;
  169. }
  170. int     menu(int x, int y, int no, char *arg[])
  171. {
  172.     int i, n, r, ch;
  173.     int len, max, mid, btm;
  174.     int od;
  175.     int rc = FALSE;
  176.     char form[64];
  177.     static int top = 0;
  178.  
  179.     for ( len = max = 0 ; arg[max] != NULL ; max++ ) {
  180.     if ( (i = strlen(arg[max])) > len )
  181.         len = i;
  182.     }
  183.  
  184.     if ( (y + max + 1) >= SCR_Y )
  185.     btm = SCR_Y - y - 1;
  186.     else
  187.     btm = max;
  188.  
  189.     if ( (x + len) > (SCR_X - 2) ) {
  190.     if ( (x = SCR_X - 2 - len) < 2 )
  191.         x = 2;
  192.     if ( (x + len) > (SCR_X - 2) )
  193.         len = (SCR_X - 2 - x);
  194.     }
  195.  
  196.     if ( max > btm && (len * 2 + 2) < (SCR_X - 4) ) {
  197.     mid = (max + btm - 1) / btm;
  198.     if ( ((len + 1) * mid) > (SCR_X - 4) )
  199.         mid = (SCR_X - 4) / (len + 1);
  200.     if ( (x + (len + 1) * mid) > (SCR_X - 2) )
  201.         x = SCR_X - 2 - (len + 1) * mid;
  202.     } else
  203.     mid = 1;
  204.  
  205.     sprintf(form, "%%-%d.%ds", len, len);
  206.  
  207.     CUROFF();
  208.     ACTCOL();
  209.     wind(x, y, (mid > 1 ? ((len + 1) * mid) : len), btm);
  210.     STDCOL();
  211.  
  212.     if ( no <= 0 )
  213.     no = top = 0;
  214.     else if ( max == btm || top >= max )
  215.     top = 0;
  216.     else
  217.     top = (top / btm) * btm;
  218.     od = (-1);
  219.  
  220.     while ( rc == FALSE ) {
  221.  
  222.         if ( od != no ) {
  223.         if ( od < 0 || no < top || no >= (top + (btm * mid)) ) {
  224.         while ( no < top )
  225.             top -= btm;
  226.         while ( no >= (top + (btm * mid)) )
  227.             top += btm;
  228.         for ( n = 0 ; n < mid ; n++ ) {
  229.             for ( i = 0 ; i < btm ; i++ ) {
  230.             LOCATE(x + (len + 1) * n, y + i);
  231.             r = i + btm * n + top;
  232.             if ( r == no )
  233.                 REVCOL();
  234.             if ( r >= max )
  235.                 REPCHR(' ', len);
  236.             else
  237.                 FPUTS(form, arg[r]);
  238.             if ( r == no )
  239.                 NOMCOL();
  240.             }
  241.         }
  242.         } else {
  243.                 LOCATE(x + (len + 1) * ((od - top) / btm),
  244.                y + (od - top) % btm);
  245.                 FPUTS(form, arg[od]);
  246.                 LOCATE(x + (len + 1) * ((no - top) / btm),
  247.                y + (no - top) % btm);
  248.                 REVCOL();
  249.                 FPUTS(form, arg[no]);
  250.                 NOMCOL();
  251.         }
  252.             LOCATE(x + (len + 1) * ((no - top) / btm) + len,
  253.            y + (no - top) % btm);
  254.             FLUSH();
  255.             od = no;
  256.         }
  257.  
  258.         ch = GETCH();
  259.  
  260.         switch(ch) {
  261.     case K_UP_NODE:
  262.     case K_BACK_SPC:
  263.     case 0x1E:
  264.     case 0x08:
  265.             if ( --no < 0 )
  266.                 no = max - 1;
  267.         break;
  268.  
  269.     case K_DOWN_NODE:
  270.     case 0x1F:
  271.     case 0x20:
  272.             if ( ++no >= max )
  273.                 no = 0;
  274.         break;
  275.  
  276.     case K_RIGHT_CUR:
  277.     case 0x1D:
  278.         if ( mid < 2 )
  279.         break;
  280.         if ( (no -= btm) < 0 ) {
  281.         if ( (no = (max / btm) * btm + (no + btm)) >= max )
  282.             no -= btm;
  283.         }
  284.         break;
  285.  
  286.     case K_LEFT_CUR:
  287.     case 0x1C:
  288.         if ( mid < 2 )
  289.         break;
  290.         if ( (no += btm) >= max )
  291.         no %= btm;
  292.         break;
  293.  
  294.     case K_END_LINE:
  295.         case 0x0D:
  296.             rc = TRUE;
  297.         break;
  298.  
  299.     case K_ABORT:
  300.         case 0x1B:
  301.             rc = ERR;
  302.         break;
  303.  
  304.         default:
  305.         if ( (ch & 0xFF00) != 0 )
  306.         rc = ERR;
  307.         else {
  308.                 for ( i = 0 ; i < max ; i++ ) {
  309.                     if ( toupper(ch) == *arg[i] ) {
  310.                         no = i;
  311.                         rc = TRUE;
  312.             }
  313.                 }
  314.             }
  315.         break;
  316.         }
  317.     }
  318.  
  319.     CURON();
  320.     return (rc == TRUE ? no : (-1));
  321. }
  322.